﻿using Sidvall.Serialization;
using System.Collections.Generic;

namespace WebOptimizer.Workflow
{
	public class ExecuteTaskJob : Sidvall.Workflow.WorkItemBase
	{
		#region Public Members

		#region Settings

		public override string Settings
		{
			get
			{
				return base.Settings;
			}
			set
			{
				base.Settings = value;
				this._Task = null;
			}
		}

		#endregion

		#region ExecuteAsync

		public async override System.Threading.Tasks.Task ExecuteAsync()
		{
			IEnumerable<string> filePaths;
			List<string> ignoredFiles;
			System.Text.StringBuilder sb;
			Sidvall.IO.SearchOption searchOption;
			string[] searchPatterns;
			string code;
			bool validFile;

			if (this.Task == null)
				return;
			if (this.Task.Sources == null)
				return;
			if (!this.Task.IsEnabled)
				return;
			if (string.IsNullOrWhiteSpace(this.Task.Path))
				return;
			if (!await Sidvall.SystemContext.Current.FileSystemManager.FolderExistsAsync(System.IO.Path.GetDirectoryName(this.Task.Path)).ConfigureAwait(false))
				return;

			// Read all files
			sb = new System.Text.StringBuilder();
			foreach (var source in this.Task.Sources)
			{
				if (!source.IsEnabled)
					continue;
				if (!await Sidvall.SystemContext.Current.FileSystemManager.FolderExistsAsync(source.Path).ConfigureAwait(false))
					continue;
				searchPatterns = source.SearchPatterns.Split(ItemSeperator, System.StringSplitOptions.RemoveEmptyEntries);
				ignoredFiles = new List<string>();
				ignoredFiles.AddRange(source.IgnoredFiles.Split(ItemSeperator, System.StringSplitOptions.RemoveEmptyEntries));
				if (source.IncludeSubfolders)
					searchOption = Sidvall.IO.SearchOption.AllDirectories;
				else
					searchOption = Sidvall.IO.SearchOption.TopDirectoryOnly;
				filePaths = await Sidvall.SystemContext.Current.FileSystemManager.GetFileNamesAsync(source.Path, searchPatterns, searchOption).ConfigureAwait(false);
				foreach (var filePath in filePaths)
				{
					validFile = true;
					foreach (var ignoredFile in ignoredFiles)
					{
						if (filePath.EndsWith(ignoredFile, System.StringComparison.OrdinalIgnoreCase))
						{
							validFile = false;
							break;
						}
					}
					if (validFile)
						sb.AppendLine(await Sidvall.SystemContext.Current.FileSystemManager.ReadAllTextAsync(filePath).ConfigureAwait(false));
				}
			}

			switch (this.Task.TaskTypeId)
			{
				case WebOptimizer.Data.TaskType.CompressCss:
					if (sb.Length > 0)
						code = WebOptimizer.SystemContext.Current.CssCompressor.Compress(sb.ToString());
					else
						code = string.Empty;
					await Sidvall.SystemContext.Current.FileSystemManager.WriteAllTextAsync(this.Task.Path, code).ConfigureAwait(false);
					break;
				default:
					if (sb.Length > 0)
						code = WebOptimizer.SystemContext.Current.JavaScriptCompressor.Compress(sb.ToString());
					else
						code = string.Empty;
					await Sidvall.SystemContext.Current.FileSystemManager.WriteAllTextAsync(this.Task.Path, code).ConfigureAwait(false);
					break;
			}
		}

		#endregion

		#endregion
		#region Private Members

		private const string ItemSeperator = "|";

		private WebOptimizer.Data.ITask _Task;
		private WebOptimizer.Data.ITask Task
		{
			get
			{
				if (_Task == null)
					_Task = Sidvall.SystemContext.Current.Serializer.Deserialize<WebOptimizer.Net.Services.V1.Task>(this.Settings);
				return _Task;
			}
		}

		#endregion
	}
}
